<?php
class Db
{
    /**
     * @desc    配置信息
     * @var null
     */
    protected $setting = null;

    /**
     * @desc    pdo对象
     * @var null
     */
    protected static $pdo = null;

    /**
     * @desc
     * @param string $dbname    数据库标识
     */
    public function __construct($dbname = 'm')
    {
        $this->connect($dbname); 
    }

    /**
     * @desc    数据库连接
     * @return null|PDO
     */
    protected function connect($dbname)
    {
        if(!self::$pdo)
        {
            // 获取数据库配置信息
            $this->setting = Yaconf::get('db')[$dbname];
           // print_r($this->setting);
            try
            {
                self::$pdo = new PDO("mysql:host={$this->setting['hostname']};port={$this->setting['port']};dbname={$this->setting['database']}", $this->setting['username'], $this->setting['password']);
                self::$pdo->query("set names {$this->setting['charset']}");
            }
            catch(PDOException $e)
            {
                exit('PDOException: ' . $e->getMessage());
            }
        }
    }

    /**
     * @desc    执行SQL语句
     * @param string $sql           SQL语句
     * @param array $parameters     需要绑定的参数值
     * @param int   $fetchmode
     * @return null
     */
    public function query($sql, $parameters = array(), $fetchmode = PDO::FETCH_ASSOC)
    {
        $stmt = self::$pdo->prepare($sql);
        $stmt->execute($parameters);
        $rawStatement = explode(" ", preg_replace("/\s+|\t+|\n+/", " ", $sql));
        $statement = strtolower($rawStatement[0]);
        if($statement === 'select')
        {
            return $stmt->fetchAll($fetchmode);
        }
        elseif($statement === 'insert' || $statement === 'update' || $statement === 'delete')
        {
            return $stmt->rowCount();
        }
        else
        {
            return null;
        }
    }
    /**
     * @author  dichaofeng
     * @desc    执行SQL语句 返回一行数据
     * @param string $sql           SQL语句
     * @param array $parameters     需要绑定的参数值
     * @param int   $fetchmode     查询模式
     * @return null
     */
    public function get_one($sql, $parameters = array(), $fetchmode = PDO::FETCH_ASSOC)
    {
        $stmt = self::$pdo->prepare($sql);
        $stmt->execute($parameters);

        $rawStatement = explode(" ", preg_replace("/\s+|\t+|\n+/", " ", $sql));
        $statement = strtolower($rawStatement[0]);
        if($statement === 'select')
        {
            return $stmt->fetch($fetchmode);

        }
        elseif($statement === 'insert' || $statement === 'update' || $statement === 'delete')
        {
            return $stmt->rowCount();
        }
        else
        {
            return null;
        }
    }
    //查询枚举列
    public function select($sql)
    {
        $result = self::$pdo->query($sql)->fetch();
        $enum=$result['Type'];
        $enum_arr=explode("(",$enum);
        $enum=$enum_arr[1];
        $enum_arr=explode(")",$enum);
        $enum=$enum_arr[0];
        $enum_arr=explode(",",$enum);
        return $enum_arr;
    }

    /**
     * @desc    获取最后插入ID
     * @return mixed
     */
    public function lastInsertId()
    {
        return self::$pdo->lastInsertId();
    }

    /**
     * @desc 添加一条记录
     * @param string $tableName 数据库表名
     * @param array  $data      需要添加的数据，如：array('field1'=>'value1', 'field2'=>'value2')
     * @return int 返回影响行数
     */
    public function insert($tableName, array $data)
    {
        $fields = '`' . implode('`,`', array_keys($data)) . '`';
        $values = implode(',', array_fill(0, count($data), '?'));
        $sql = "INSERT INTO `{$tableName}`({$fields}) VALUES ({$values})";
        return $this->query($sql, array_values($data));
    }

    /**
     * @desc 添加多条数据
     * @param string $tableName 数据库表名
     * @param array  $data      需要添加的数据，为一个二维数组，如：$data = array(array('fileld1'=>'value1','fileld2'=>'value2'),array('fileld1'=>'value1','fileld2'=>'value2'))
     * @return int 返回影响行数
     */
    public function insertBatch($tableName, array $data)
    {
        $fields = '`' . implode('`,`', array_keys($data[0])) . '`';
        $tmp  = $tmp2 = array();
        foreach($data as $value)
        {
            $tmp[] = implode(',', array_fill(0, count($value), '?'));
            foreach($value as $v)
            {
                $tmp2[] = $v;
            }
        }
        $values = "(" . implode("),(", $tmp) . ")";
        $sql = "INSERT INTO `{$tableName}`({$fields}) VALUES {$values}";
        return $this->query($sql, $tmp2);
    }

    /**
     * @desc 更新
     * @param string $tableName 数据库表名
     * @param array  $where     更新条件，为 key|value 对应的数组，如：array('id'=>233)
     * @param array  $data      更新数据，为 key|value 对应的数组，如：array('field1'=>'value1','field12'=>'value2')
     * @param array  $other     参照  formatOhterCondition 中的参数说明
     * @return int 返回影响行数
     */
    public function update($tableName, array $where, array $data, array $other=array())
    {
        if(!$where || !$data){return false;}
        $tmp1 = $tmp2 = $tmp3 = array();
        // 条件
        foreach($where as $key=>$value)
        {
            $tmp1[] = "{$key}=?";
            $tmp2[] = $value;
        }
        $tmp1 = implode(' and ', $tmp1);
        // 组合更新数据
        foreach($data as $key=>$value)
        {
            $tmp3[] = "`{$key}`='{$value}'";
        }
        $tmp3 = implode(',', $tmp3);
        $other = $this->formatOhterCondition($other);
        $sql = "UPDATE `{$tableName}` SET {$tmp3} WHERE {$tmp1} {$other}";
        return $this->query($sql, $tmp2);
    }

    /**
     * @desc 删除
     * @param string $tableName 数据库表名
     * @param array  $where     删除条件，为 key|value 对应的数组，如：array('id'=>233)
     * @param array  $other     参照  formatOhterCondition 中的参数说明
     * @return int 返回影响行数
     */
    public function delete($tableName, array $where, array $other=array())
    {
        if(!$where){return false;}
        $tmp1 = $tmp2 = array();
        // 条件
        foreach($where as $key=>$value)
        {
            $tmp1[] = "{$key}=?";
            $tmp2[] = $value;
        }
        $tmp1 = implode(' and ', $tmp1);
        $other = $this->formatOhterCondition($other);
        $sql = "DELETE FROM `{$tableName}` WHERE {$tmp1} {$other}";
        return $this->query($sql, $tmp2);
    }

    /**
     * @desc    开启事务
     * @return mixed
     */
    public function beginTransaction()
    {
        return self::$pdo->beginTransaction();
    }

    /**
     * @desc    提交事务
     * @return mixed
     */
    public function executeTransaction()
    {
        return self::$pdo->commit();
    }

    /**
     * @desc    回滚事务
     * @return mixed
     */
    public function rollBack()
    {
        return self::$pdo->rollBack();
    }

    /**
     * @desc    格式化 where 条件
     * @param string|array $where
     *          字符串: id=1 and field1=value1
     *          数组: array(
     *                      array('id', '=', 1),
     *                      array('field1', '=', 'value1'),
     *                      array('field2', 'in', array(1,2,3)),
     *                  )
     * @return string
     */
    public function formatWhere($where)
    {
        // 字符串
        if(!is_array($where))
        {
            if($where){return " where {$where}";}
            return '';
        }
        // 空数组
        if(!$where){return '';}
        $tmp = array();
        foreach($where as $value)
        {
            switch($value[1])
            {
                case 'in':
                    $value[2] = '('.implode(',', $value[2]).')';
                    $tmp[] = "{$value[0]} {$value[1]} {$value[2]}";
                    break;
                default:
                    $tmp[] = "{$value[0]} {$value[1]} '{$value[2]}'";
                    break;
            }
        }
        $where = implode(' and ', $tmp);
        return " where {$where}";
    }

    /**
     * @desc    格式化其他条件
     * @param array $other = array(
                        'order'=>'id desc',
                        'limit'=>'0,10',
                        );
     * @return string
     */
    public function formatOhterCondition(array $other = array())
    {
        if(!$other){return '';}
        $tmp = '';
        foreach($other as $key=>$value)
        {
            if($key === 'order'){$tmp .= " order by {$value}";}
            if($key === 'limit'){$tmp .= " limit {$value}";}
        }
        return $tmp;
    }
    /*
     * 获取 GET 中的参数，只需要调用 C_Basic.php 中的 get() 即可
 $username = $this->get('username');
获取 POST 中的参数，只需要调用 C_Basic.php 中的 getPost() 即可
 $username = $this->getPost('username');
      <?php
     class IndexController extends Yaf_Controller_Abstract {
        public funciton init() {
            $this->getResponse()->setRedirect("http://domain.com/");
        }
     }
     ?>

     */
    /*
     *
     <?php
     class IndexController extends Yaf_Controller_Abstract {
        public funciton init() {
           /**
            * 如果用户没登陆, 则转给登陆动作
     * if($user_not_login) {
         $this->forward("login");
                            }
                }
               }
?>
            */



}
